package deng.spring;

import java.util.Arrays;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

/**
 * Start a spring container and wait for shutdown (CTRL+C).
 * 
 * Usage: java QuartzServer [spring-beans.xml ...]
 */
public class SpringServer
{
	/** A slf4j logger. */
	private static Logger logger = LoggerFactory.getLogger(SpringServer.class);
	
	private ConfigurableApplicationContext appCtx;
	
	private String[] xmlFiles;
	
	public void setXmlFiles(String[] xmlFiles)
	{
		this.xmlFiles = xmlFiles;
	}
	
	public void run()
	{
		start();
		registerShutdownEvent();
		waitForShutdownEvent();
	}
	
	public void start()
	{
		logger.debug("Starting spring: " + Arrays.asList(xmlFiles));
		appCtx = new FileSystemXmlApplicationContext(xmlFiles);
	}
	
	public void stop()
	{
		logger.debug("Stopping spring: " + appCtx);
		appCtx.stop();
	}
	
	private void waitForShutdownEvent()
	{
		logger.debug("Wait and block current thread.");
		synchronized(this) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				throw new RuntimeException(e);
			}
		}
	}
	private void notifyShutdownEvent()
	{
		logger.debug("Notify all waiting thread.");
		synchronized(this) {
			this.notifyAll();
		}
	}

	private void registerShutdownEvent()
	{
		logger.debug("Registering a shutdown event with Java Runtime#shutdownHook.");
		Runtime.getRuntime().addShutdownHook(new Thread(){
			
			@Override
			public void run()
			{	
				logger.debug("Shutdown started.");
				SpringServer.this.stop();
				notifyShutdownEvent();
			}
			
		});
	}
	
	public static void main(String[] args)
	{
		SpringServer main = new SpringServer();
		main.setXmlFiles(args);
		main.run();
	}
}
